﻿using DxfMonitor.Data;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;

namespace DxfMonitor.ViewModel
{
    public class FolderPairViewModel : ObservableObject
    {
        private readonly bool isCreatingInstance;
        public FolderPairViewModel(DxfPair dxfPair)
        {
            isCreatingInstance = true;
            LastFolderFull = dxfPair.LastFolder.FolderFull;
            CurrentFolderFull = dxfPair.CurrentFolder.FolderFull;
            Guid = dxfPair.Guid;
            BaseDate = dxfPair.LastFolder.BaseDate;
            CheckIfCan();
            isCreatingInstance = false;
            LoadLasts();
        }

        public void AutoFillOtherFolder()
        {
            if (Directory.Exists(CurrentFolderFull) && !Directory.Exists(LastFolderFull))
            {
                LastFolderFull = CurrentFolderFull;
            }
        }

        private int lastSavedHash = 0;
        private void AsyncSavePair()
        {
            Task.Run(() =>
            {
                if (isCreatingInstance)
                {
                    return;
                }
                int hash = HashCode.Combine(LastFolderFull, CurrentFolderFull, IsChecked);
                if (lastSavedHash != hash)
                {
                    Repository.SavePairAndFolder(this);
                    DateTime newBaseDate = Repository.QueryFolderBaseDate(LastFolderFull);
                    if (newBaseDate != BaseDate)
                    {
                        LoadLasts();
                    }
                    lastSavedHash = hash;
                }
            });
        }

        private string currentFolderFull;
        public string CurrentFolderFull
        {
            get => currentFolderFull;
            set
            {
                SetProperty(ref currentFolderFull, value);
                CheckIfCan();
                OnPropertyChanged(nameof(CurrentFolder));
                AutoFillOtherFolder();
                AsyncSavePair();
            }
        }

        public string CurrentFolder
        {
            get => Path.GetFileName(CurrentFolderFull);
        }

        private string lastFolderFull;
        public string LastFolderFull
        {
            get => lastFolderFull;
            set
            {
                SetProperty(ref lastFolderFull, value);
                CheckIfCan();
                OnPropertyChanged(nameof(LastFolder));
                AsyncSavePair();
            }
        }
        public string LastFolder
        {
            get => Path.GetFileName(LastFolderFull);
        }

        private IList<DxfHistoryStatus> Lasts = new List<DxfHistoryStatus>();
        public bool HasHistory
        {
            get => Shared.IsDateInitialized(BaseDate);
        }
        public void LoadLasts()
        {
            if (!isClearning)
            {
                Lasts = Repository.QueryLastDxfHistoryStatuses(LastFolderFull, out baseDate);
                Added = new ObservableCollection<DxfHistoryStatus>();
                Removed = new ObservableCollection<DxfHistoryStatus>();
                OnPropertyChanged(nameof(BaseDate));
            }
        }



        public string Guid
        {
            get;
            private set;
        }

        private bool isChecked;
        public bool IsChecked
        {
            get => isChecked;
            set
            {
                SetProperty(ref isChecked, value);
                if (MainViewModel.Main != null)
                {
                    MainViewModel.Main.RunCommand.NotifyCanExecuteChanged();
                }
                AsyncSavePair();
            }
        }

        private DateTime baseDate;
        public DateTime BaseDate
        {
            get => baseDate;
            set => SetProperty(ref baseDate, value);
        }

        private void CheckIfCan()
        {
            IsChecked = CanCheck;
            if(CurrentFolderFull!=null && CurrentFolderFull.EndsWith("net6.0-windows"))
            {
                Debug.WriteLine($"IsChecked={IsChecked}");
            }
        }
        public bool CanCheck => Directory.Exists(CurrentFolderFull)
            && Directory.Exists(LastFolderFull);

        private ObservableCollection<DxfHistoryStatus> added;
        public ObservableCollection<DxfHistoryStatus> Added
        {
            get => added;
            set => SetProperty(ref added, value);
        }
        private ObservableCollection<DxfHistoryStatus> removed;
        public ObservableCollection<DxfHistoryStatus> Removed
        {
            get => removed;
            set => SetProperty(ref removed, value);
        }
        public void CompareFiles(bool autoUpdate)
        {
            DxfComparer dxfComparer = new DxfComparer(LastFolderFull, CurrentFolderFull);
            var current = dxfComparer.ScanDxfInfos().ToList();
            DateTime now = DateTime.Now;
            IList<DxfHistoryStatus> added1;
            IList<DxfHistoryStatus> removed1;
            if (HasHistory)
            {
                if (autoUpdate)
                {
                    Lasts = current;
                    Task.Run(() =>
                    {
                        Repository.SaveLasts(Lasts, CurrentFolderFull, BaseDate);
                    });
                }
                dxfComparer.Compare2DxfHistoryStatuses(Lasts, current, out added1, out removed1);

            }

            //
            else
            {
                BaseDate = now;

                if (autoUpdate)
                {
                    Lasts = current;
                    Task.Run(() =>
                    {
                        Repository.SaveLasts(Lasts, CurrentFolderFull, BaseDate);
                    });
                    dxfComparer.Compare2DxfHistoryStatuses(Lasts, current, out added1, out removed1);
                }
                else
                {
                    Lasts = DxfComparer.ScanDxfInfosOfFolder(LastFolderFull);
                    Task.Run(() =>
                    {
                        Repository.SaveLasts(Lasts, CurrentFolderFull, BaseDate);
                    });
                    dxfComparer.Compare2DxfHistoryStatuses(Lasts, current, out added1, out removed1);

                }


            }
            Added = new ObservableCollection<DxfHistoryStatus>(added1);
            Removed = new ObservableCollection<DxfHistoryStatus>(removed1);
        }

        private RelayCommand clearCommand;
        public RelayCommand ClearCommand => clearCommand ?? (clearCommand = new RelayCommand(ExecuteClearCommand, CanExecuteClearCommand));

        private bool CanExecuteClearCommand()
        {
            return !string.IsNullOrWhiteSpace(LastFolderFull)
                || !string.IsNullOrWhiteSpace(CurrentFolderFull)
               || this.IsChecked;
            //return false;
        }



        private bool isClearning;
        private void ExecuteClearCommand()
        {
            isClearning = true;
            ClearCommand.NotifyCanExecuteChanged();
            Task.Run(() =>
            {
                Repository.ClearPair(this);
                Application.Current.Dispatcher.BeginInvoke((Action)delegate
                {
                    CurrentFolderFull = "";
                    LastFolderFull = "";
                    IsChecked = false;
                    BaseDate = new DateTime();
                    ClearCommand.NotifyCanExecuteChanged();
                    isClearning = false;
                });
            });
        }

    }
}
